library(tidyverse)
library(cowplot)
library(maps)
library(ggforce)
library(viridis)
# library(ggthemes)
studies <- read_csv("../data/studies_gsheet.csv")
sites <- read_csv("../data/sites_gsheet.csv")
df <- studies %>%
group_by(site) %>%
summarise(Nstudies = n_distinct(studyID),
Nspecies = n_distinct(species)) %>%
mutate(legend_species = ifelse(Nspecies > 4, "more ", Nspecies))%>%
left_join(sites)
Joining, by = "site"
df %>%
arrange(desc(Nspecies), desc(Nstudies)) %>%
mutate(site2 = str_sub(site, 1, 60)) %>%
select(site2, Nstudies, Nspecies)
# sanity check that coordinates are in the right country
# within a country, all Xs should be the same color
ggplot(df, aes(x = long, y = lat)) +
geom_polygon(data = world, aes(group = group), col = "black", fill = "grey90") +
geom_point(aes(col = country), size = 5, shape = 4, stroke = 2, alpha = .8) +
coord_fixed(1.3, ylim = c(-55, 83.59961)) +
scale_color_viridis_d() +
theme_map() +
guides(col = "none")

Col & Size = #studies
m <- ggplot(df, aes(x = long, y = lat)) +
geom_polygon(data = world, aes(group = group), fill = "grey90") +
geom_point(aes(size = Nstudies, fill = Nstudies), shape = 21, alpha = .8) +
theme_map() +
# # to make fill into discrete; overlap with size legend
# scale_size_area("Number of\nStudies", max_size = 15) +
# scale_fill_viridis_c("Number of\nStudies", guide = "legend") +
# to have them side by side
scale_fill_viridis_c("", breaks = c(1, 20, 40, 60)) +
scale_size_area("", max_size = 15, breaks = c(1, 20, 40, 60)) +
theme(legend.box = "horizontal") +
guides(fill = guide_colorbar(reverse = T, barheight = 10, order = 0),
size = guide_legend(keyheight = 2.6, title.theme = element_text(size = 4)))
legend <- get_legend(m)
Removed 3 rows containing missing values (geom_point).
# plot_grid(legend)
mx <- m +
annotate("rect", ymin = c(24, 31, 24), ymax = c(46, 62, 50), xmin = c(124, -12, -130),
xmax = c(146, 32, -64), size = .5, col = "grey", fill = NA) +
coord_fixed(1.3, ylim = c(-55, 83.59961)) +
theme(legend.position = "none")
# japan
m1 <- m +
geom_polygon(data = world, aes(group = group), col = "black", fill = "grey90", lwd = .2) +
geom_point(aes(size = Nstudies, fill = Nstudies), shape = 21, alpha = .8) +
coord_fixed(1.3, ylim = c(25, 45), xlim = c(125, 145)) +
theme(legend.position = "none") +
panel_border(color = "grey", size = .5)
# europe
m2 <- m +
geom_polygon(data = world, aes(group = group), col = "black", fill = "grey90", lwd = .2) +
geom_point(aes(size = Nstudies, fill = Nstudies), shape = 21, alpha = .8) +
coord_fixed(1.3, ylim = c(32, 60), xlim = c(-10, 30)) +
theme(legend.position = "none") +
panel_border(color = "grey", size = .5)
# contiguous us
usa = map("state", plot = FALSE, fill = TRUE) %>% fortify() # "usa"
m3 <- m +
geom_polygon(data = world, aes(group = group), col = "black", fill = "grey90", lwd = .2) +
geom_polygon(data = usa, aes(group = group), col = "black", fill = "grey90", lwd = .2) +
geom_point(aes(size = Nstudies, fill = Nstudies), shape = 21, alpha = .8) +
coord_fixed(1.3, ylim = c(25, 49), xlim = c(-127, -67)) +
theme(legend.position = "none") +
panel_border(color = "grey", size = .5)
# make bottom row (3 map insets + legend)
bottom_row <- plot_grid(m3, m2, NA, m1, NA, legend, nrow = 1, label_x = -.35, label_y = .95,
labels = c(rep("", 5), "Number of Studies"),
rel_widths = c(2, 1.18, .06, .85, .08, .7))
Removed 3 rows containing missing values (geom_point).Removed 3 rows containing missing values (geom_point).Removed 3 rows containing missing values (geom_point).Removed 3 rows containing missing values (geom_point).Cannot convert object of class logical into a grob.Removed 3 rows containing missing values (geom_point).Removed 3 rows containing missing values (geom_point).Cannot convert object of class logical into a grob.
# make whole plot as 1 column, big map on top, bottom row underneath
plot_grid(mx, bottom_row, ncol = 1, rel_heights = c(2.4, 1)) +
theme(plot.margin = unit(c(.5, .5, 1.5, .5), "cm"))
Removed 3 rows containing missing values (geom_point).

Col = #species, Size = #studies
ms <- ggplot(df, aes(x = long, y = lat)) +
geom_polygon(data = world, aes(group = group), fill = "grey90") +
geom_point(aes(size = Nstudies, fill = legend_species), shape = 21, alpha = .8) +
theme_map() +
# to have them side by side
scale_fill_brewer("Species", palette = "Greens") +
scale_size_area("Studies", max_size = 15, breaks = c(1, 20, 40, 60)) +
theme(legend.box = "horizontal") +
guides(fill = guide_legend(override.aes = list(size = 6), keyheight = 1.6, order = 1),
size = guide_legend(keyheight = 1.6, order = 0))
legend <- get_legend(ms)
Removed 3 rows containing missing values (geom_point).
# plot_grid(legend)
msx <- ms +
annotate("rect", ymin = c(24, 31, 24), ymax = c(46, 62, 50), xmin = c(124, -12, -130),
xmax = c(146, 32, -64), size = .5, col = "grey", fill = NA) +
coord_fixed(1.3, ylim = c(-55, 83.59961)) +
theme(legend.position = "none")
# japan
ms1 <- ms +
geom_polygon(data = world, aes(group = group), col = "black", fill = "grey90", lwd = .2) +
geom_point(aes(size = Nstudies, fill = legend_species), shape = 21, alpha = .8) +
coord_fixed(1.3, ylim = c(25, 45), xlim = c(125, 145)) +
theme(legend.position = "none") +
panel_border(color = "grey", size = .5)
# europe
ms2 <- ms +
geom_polygon(data = world, aes(group = group), col = "black", fill = "grey90", lwd = .2) +
geom_point(aes(size = Nstudies, fill = legend_species), shape = 21, alpha = .8) +
coord_fixed(1.3, ylim = c(32, 60), xlim = c(-10, 30)) +
theme(legend.position = "none") +
panel_border(color = "grey", size = .5)
# contiguous us
usa = map("state", plot = FALSE, fill = TRUE) %>% fortify() # "usa"
ms3 <- ms +
geom_polygon(data = world, aes(group = group), col = "black", fill = "grey90", lwd = .2) +
geom_polygon(data = usa, aes(group = group), col = "black", fill = "grey90", lwd = .2) +
geom_point(aes(size = Nstudies, fill = legend_species), shape = 21, alpha = .8) +
coord_fixed(1.3, ylim = c(25, 49), xlim = c(-127, -67)) +
theme(legend.position = "none") +
panel_border(color = "grey", size = .5)
# make bottom row (3 map insets + legend)
bottom_row <- plot_grid(ms3, ms2, NA, ms1, NA, legend, nrow = 1, label_x = -.27, label_y = .93,
labels = c(rep("", 5), "Number of ..."),
rel_widths = c(2, 1.18, .06, .85, .08, .7))
Removed 3 rows containing missing values (geom_point).Removed 3 rows containing missing values (geom_point).Removed 3 rows containing missing values (geom_point).Removed 3 rows containing missing values (geom_point).Cannot convert object of class logical into a grob.Removed 3 rows containing missing values (geom_point).Removed 3 rows containing missing values (geom_point).Cannot convert object of class logical into a grob.
# make whole plot as 1 column, big map on top, bottom row underneath
plot_grid(msx, bottom_row, ncol = 1, rel_heights = c(2.4, 1)) +
theme(plot.margin = unit(c(.5, .5, 1.5, .5), "cm"))
Removed 3 rows containing missing values (geom_point).

Session Info
sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.5
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] viridis_0.5.1 viridisLite_0.3.0 ggforce_0.3.1 maps_3.3.0 cowplot_1.0.0
[6] forcats_0.4.0 stringr_1.4.0 dplyr_0.8.3 purrr_0.3.2 readr_1.3.1
[11] tidyr_1.0.0 tibble_2.1.3 ggplot2_3.2.1 tidyverse_1.2.1
loaded via a namespace (and not attached):
[1] Rcpp_1.0.2 lubridate_1.7.4 lattice_0.20-38 prettyunits_1.0.2 ps_1.3.0
[6] assertthat_0.2.1 zeallot_0.1.0 digest_0.6.21 R6_2.4.0 cellranger_1.1.0
[11] backports_1.1.5 stats4_3.6.1 evaluate_0.14 httr_1.4.1 pillar_1.4.2
[16] rlang_0.4.0 lazyeval_0.2.2 readxl_1.3.1 rstudioapi_0.10 callr_3.3.2
[21] rmarkdown_1.16 labeling_0.3 loo_2.1.0 polyclip_1.10-0 munsell_0.5.0
[26] broom_0.5.2 compiler_3.6.1 modelr_0.1.5 xfun_0.10 rstan_2.19.2
[31] pkgconfig_2.0.3 base64enc_0.1-3 pkgbuild_1.0.5 htmltools_0.4.0 tidyselect_0.2.5
[36] gridExtra_2.3 matrixStats_0.55.0 crayon_1.3.4 withr_2.1.2 MASS_7.3-51.4
[41] grid_3.6.1 nlme_3.1-141 jsonlite_1.6 gtable_0.3.0 lifecycle_0.1.0
[46] magrittr_1.5 StanHeaders_2.19.0 scales_1.0.0 cli_1.1.0 stringi_1.4.3
[51] farver_1.1.0 xml2_1.2.2 generics_0.0.2 vctrs_0.2.0 RColorBrewer_1.1-2
[56] tools_3.6.1 glue_1.3.1 tweenr_1.0.1 hms_0.5.1 parallel_3.6.1
[61] processx_3.4.1 inline_0.3.15 colorspace_1.4-1 rvest_0.3.4 knitr_1.25
[66] haven_2.1.1
LS0tCnRpdGxlOiAiU2l0ZXMiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgY3NzOiBzdHlsZS5jc3MKICAgIHRoZW1lOiBwYXBlcgotLS0KCmBgYHtyIHNldHVwLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShjb3dwbG90KQpsaWJyYXJ5KG1hcHMpCmxpYnJhcnkoZ2dmb3JjZSkKbGlicmFyeSh2aXJpZGlzKQojIGxpYnJhcnkoZ2d0aGVtZXMpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0V9CnN0dWRpZXMgPC0gcmVhZF9jc3YoIi4uL2RhdGEvc3R1ZGllc19nc2hlZXQuY3N2IikKc2l0ZXMgPC0gcmVhZF9jc3YoIi4uL2RhdGEvc2l0ZXNfZ3NoZWV0LmNzdiIpCmBgYAoKYGBge3J9CmRmIDwtIHN0dWRpZXMgJT4lIAogIGdyb3VwX2J5KHNpdGUpICU+JSAKICBzdW1tYXJpc2UoTnN0dWRpZXMgPSBuX2Rpc3RpbmN0KHN0dWR5SUQpLAogICAgICAgICAgICBOc3BlY2llcyA9IG5fZGlzdGluY3Qoc3BlY2llcykpICU+JSAKICBtdXRhdGUobGVnZW5kX3NwZWNpZXMgPSBpZmVsc2UoTnNwZWNpZXMgPiA0LCAibW9yZSAgICAgICIsIE5zcGVjaWVzKSklPiUKICBsZWZ0X2pvaW4oc2l0ZXMpCmBgYAoKYGBge3J9CmRmICU+JSAKICBhcnJhbmdlKGRlc2MoTnNwZWNpZXMpLCBkZXNjKE5zdHVkaWVzKSkgJT4lIAogIG11dGF0ZShzaXRlMiA9IHN0cl9zdWIoc2l0ZSwgMSwgNjApKSAlPiUgCiAgc2VsZWN0KHNpdGUyLCBOc3R1ZGllcywgTnNwZWNpZXMpCmBgYAoKYGBge3J9CndvcmxkIDwtIG1hcCgid29ybGQiLCBwbG90ID0gRkFMU0UsIGZpbGwgPSBUUlVFKSAlPiUgZm9ydGlmeSgpCmBgYAoKYGBge3IsIGZpZy53aWR0aD0yMCwgZmlnLmhlaWdodD0xMCwgY2FjaGU9VFJVRX0KIyBzYW5pdHkgY2hlY2sgdGhhdCBjb29yZGluYXRlcyBhcmUgaW4gdGhlIHJpZ2h0IGNvdW50cnkKIyB3aXRoaW4gYSBjb3VudHJ5LCBhbGwgWHMgc2hvdWxkIGJlIHRoZSBzYW1lIGNvbG9yCmdncGxvdChkZiwgYWVzKHggPSBsb25nLCB5ID0gbGF0KSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGQsIGFlcyhncm91cCA9IGdyb3VwKSwgY29sID0gImJsYWNrIiwgZmlsbCA9ICJncmV5OTAiKSArCiAgZ2VvbV9wb2ludChhZXMoY29sID0gY291bnRyeSksIHNpemUgPSA1LCBzaGFwZSA9IDQsIHN0cm9rZSA9IDIsIGFscGhhID0gLjgpICsKICBjb29yZF9maXhlZCgxLjMsIHlsaW0gPSBjKC01NSwgODMuNTk5NjEpKSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKCkgKwogIHRoZW1lX21hcCgpICsKICBndWlkZXMoY29sID0gIm5vbmUiKQpgYGAKCmBgYHtyfQpnZ3NhdmUoIi4uL2dyYXBocy9tYXAucGRmIiwgd2lkdGggPSAyMCwgaGVpZ2h0ID0gMTAsIHNjYWxlID0gMikKYGBgCgojIENvbCAmIFNpemUgPSAjc3R1ZGllcwoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTR9Cm0gPC0gZ2dwbG90KGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZCwgYWVzKGdyb3VwID0gZ3JvdXApLCBmaWxsID0gImdyZXk5MCIpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gTnN0dWRpZXMsIGZpbGwgPSBOc3R1ZGllcyksIHNoYXBlID0gMjEsIGFscGhhID0gLjgpICsKICB0aGVtZV9tYXAoKSArCiAgIyAjIHRvIG1ha2UgZmlsbCBpbnRvIGRpc2NyZXRlOyBvdmVybGFwIHdpdGggc2l6ZSBsZWdlbmQKICAjIHNjYWxlX3NpemVfYXJlYSgiTnVtYmVyIG9mXG5TdHVkaWVzIiwgbWF4X3NpemUgPSAxNSkgKwogICMgc2NhbGVfZmlsbF92aXJpZGlzX2MoIk51bWJlciBvZlxuU3R1ZGllcyIsIGd1aWRlID0gImxlZ2VuZCIpICsKICAjIHRvIGhhdmUgdGhlbSBzaWRlIGJ5IHNpZGUKICBzY2FsZV9maWxsX3ZpcmlkaXNfYygiIiwgYnJlYWtzID0gYygxLCAyMCwgNDAsIDYwKSkgKwogIHNjYWxlX3NpemVfYXJlYSgiIiwgbWF4X3NpemUgPSAxNSwgYnJlYWtzID0gYygxLCAyMCwgNDAsIDYwKSkgKwogIHRoZW1lKGxlZ2VuZC5ib3ggPSAiaG9yaXpvbnRhbCIpICsKICBndWlkZXMoZmlsbCA9IGd1aWRlX2NvbG9yYmFyKHJldmVyc2UgPSBULCBiYXJoZWlnaHQgPSAxMCwgb3JkZXIgPSAwKSwgCiAgICAgICAgIHNpemUgPSBndWlkZV9sZWdlbmQoa2V5aGVpZ2h0ID0gMi42LCB0aXRsZS50aGVtZSA9IGVsZW1lbnRfdGV4dChzaXplID0gNCkpKQoKbGVnZW5kIDwtIGdldF9sZWdlbmQobSkKIyBwbG90X2dyaWQobGVnZW5kKQoKbXggPC0gbSArCiAgYW5ub3RhdGUoInJlY3QiLCB5bWluID0gYygyNCwgMzEsIDI0KSwgeW1heCA9IGMoNDYsIDYyLCA1MCksIHhtaW4gPSBjKDEyNCwgLTEyLCAtMTMwKSwgCiAgICAgICAgICAgeG1heCA9IGMoMTQ2LCAzMiwgLTY0KSwgc2l6ZSA9IC41LCBjb2wgPSAiZ3JleSIsIGZpbGwgPSBOQSkgKyAKICBjb29yZF9maXhlZCgxLjMsIHlsaW0gPSBjKC01NSwgODMuNTk5NjEpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyfQojIGphcGFuCm0xIDwtIG0gKyAKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkLCBhZXMoZ3JvdXAgPSBncm91cCksIGNvbCA9ICJibGFjayIsIGZpbGwgPSAiZ3JleTkwIiwgbHdkID0gLjIpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gTnN0dWRpZXMsIGZpbGwgPSBOc3R1ZGllcyksIHNoYXBlID0gMjEsIGFscGhhID0gLjgpICsKICBjb29yZF9maXhlZCgxLjMsIHlsaW0gPSBjKDI1LCA0NSksIHhsaW0gPSBjKDEyNSwgMTQ1KSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIHBhbmVsX2JvcmRlcihjb2xvciA9ICJncmV5Iiwgc2l6ZSA9IC41KQoKIyBldXJvcGUKbTIgPC0gbSArIAogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGQsIGFlcyhncm91cCA9IGdyb3VwKSwgY29sID0gImJsYWNrIiwgZmlsbCA9ICJncmV5OTAiLCBsd2QgPSAuMikgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBOc3R1ZGllcywgZmlsbCA9IE5zdHVkaWVzKSwgc2hhcGUgPSAyMSwgYWxwaGEgPSAuOCkgKwogIGNvb3JkX2ZpeGVkKDEuMywgeWxpbSA9IGMoMzIsIDYwKSwgeGxpbSA9IGMoLTEwLCAzMCkpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBwYW5lbF9ib3JkZXIoY29sb3IgPSAiZ3JleSIsIHNpemUgPSAuNSkKCiMgY29udGlndW91cyB1cwp1c2EgPSBtYXAoInN0YXRlIiwgcGxvdCA9IEZBTFNFLCBmaWxsID0gVFJVRSkgJT4lIGZvcnRpZnkoKSAjICJ1c2EiCgptMyA8LSBtICsgCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZCwgYWVzKGdyb3VwID0gZ3JvdXApLCBjb2wgPSAiYmxhY2siLCBmaWxsID0gImdyZXk5MCIsIGx3ZCA9IC4yKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB1c2EsIGFlcyhncm91cCA9IGdyb3VwKSwgY29sID0gImJsYWNrIiwgZmlsbCA9ICJncmV5OTAiLCBsd2QgPSAuMikgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBOc3R1ZGllcywgZmlsbCA9IE5zdHVkaWVzKSwgc2hhcGUgPSAyMSwgYWxwaGEgPSAuOCkgKwogIGNvb3JkX2ZpeGVkKDEuMywgeWxpbSA9IGMoMjUsIDQ5KSwgeGxpbSA9IGMoLTEyNywgLTY3KSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIHBhbmVsX2JvcmRlcihjb2xvciA9ICJncmV5Iiwgc2l6ZSA9IC41KQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01LjUsIGNhY2hlPVRSVUV9CiMgbWFrZSBib3R0b20gcm93ICgzIG1hcCBpbnNldHMgKyBsZWdlbmQpCmJvdHRvbV9yb3cgPC0gcGxvdF9ncmlkKG0zLCBtMiwgTkEsIG0xLCBOQSwgbGVnZW5kLCBucm93ID0gMSwgbGFiZWxfeCA9IC0uMzUsIGxhYmVsX3kgPSAuOTUsCiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMocmVwKCIiLCA1KSwgIk51bWJlciBvZiBTdHVkaWVzIiksIAogICAgICAgICAgICAgICAgICAgICAgICByZWxfd2lkdGhzID0gYygyLCAxLjE4LCAuMDYsIC44NSwgLjA4LCAuNykpCgojIG1ha2Ugd2hvbGUgcGxvdCBhcyAxIGNvbHVtbiwgYmlnIG1hcCBvbiB0b3AsIGJvdHRvbSByb3cgdW5kZXJuZWF0aApwbG90X2dyaWQobXgsIGJvdHRvbV9yb3csIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMi40LCAxKSkgKwogIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKC41LCAuNSwgMS41LCAuNSksICJjbSIpKQpgYGAKCmBgYHtyfQpnZ3NhdmUoIi4uL2dyYXBocy9tYXBfaW5zZXRzLnBkZiIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gNS41LCBzY2FsZSA9IDIpCmBgYAoKIyBDb2wgPSAjc3BlY2llcywgU2l6ZSA9ICNzdHVkaWVzCgpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NH0KbXMgPC0gZ2dwbG90KGRmLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQpKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZCwgYWVzKGdyb3VwID0gZ3JvdXApLCBmaWxsID0gImdyZXk5MCIpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gTnN0dWRpZXMsIGZpbGwgPSBsZWdlbmRfc3BlY2llcyksIHNoYXBlID0gMjEsIGFscGhhID0gLjgpICsKICB0aGVtZV9tYXAoKSArCiAgIyB0byBoYXZlIHRoZW0gc2lkZSBieSBzaWRlCiAgc2NhbGVfZmlsbF9icmV3ZXIoIlNwZWNpZXMiLCBwYWxldHRlID0gIkdyZWVucyIpICsKICBzY2FsZV9zaXplX2FyZWEoIlN0dWRpZXMiLCBtYXhfc2l6ZSA9IDE1LCBicmVha3MgPSBjKDEsIDIwLCA0MCwgNjApKSArCiAgdGhlbWUobGVnZW5kLmJveCA9ICJob3Jpem9udGFsIikgKwogIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDYpLCBrZXloZWlnaHQgPSAxLjYsIG9yZGVyID0gMSksCiAgICAgICAgIHNpemUgPSBndWlkZV9sZWdlbmQoa2V5aGVpZ2h0ID0gMS42LCBvcmRlciA9IDApKQoKbGVnZW5kIDwtIGdldF9sZWdlbmQobXMpCiMgcGxvdF9ncmlkKGxlZ2VuZCkKCm1zeCA8LSBtcyArCiAgYW5ub3RhdGUoInJlY3QiLCB5bWluID0gYygyNCwgMzEsIDI0KSwgeW1heCA9IGMoNDYsIDYyLCA1MCksIHhtaW4gPSBjKDEyNCwgLTEyLCAtMTMwKSwgCiAgICAgICAgICAgeG1heCA9IGMoMTQ2LCAzMiwgLTY0KSwgc2l6ZSA9IC41LCBjb2wgPSAiZ3JleSIsIGZpbGwgPSBOQSkgKyAKICBjb29yZF9maXhlZCgxLjMsIHlsaW0gPSBjKC01NSwgODMuNTk5NjEpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCmBgYHtyfQojIGphcGFuCm1zMSA8LSBtcyArIAogIGdlb21fcG9seWdvbihkYXRhID0gd29ybGQsIGFlcyhncm91cCA9IGdyb3VwKSwgY29sID0gImJsYWNrIiwgZmlsbCA9ICJncmV5OTAiLCBsd2QgPSAuMikgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBOc3R1ZGllcywgZmlsbCA9IGxlZ2VuZF9zcGVjaWVzKSwgc2hhcGUgPSAyMSwgYWxwaGEgPSAuOCkgKwogIGNvb3JkX2ZpeGVkKDEuMywgeWxpbSA9IGMoMjUsIDQ1KSwgeGxpbSA9IGMoMTI1LCAxNDUpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgcGFuZWxfYm9yZGVyKGNvbG9yID0gImdyZXkiLCBzaXplID0gLjUpCgojIGV1cm9wZQptczIgPC0gbXMgKyAKICBnZW9tX3BvbHlnb24oZGF0YSA9IHdvcmxkLCBhZXMoZ3JvdXAgPSBncm91cCksIGNvbCA9ICJibGFjayIsIGZpbGwgPSAiZ3JleTkwIiwgbHdkID0gLjIpICsKICBnZW9tX3BvaW50KGFlcyhzaXplID0gTnN0dWRpZXMsIGZpbGwgPSBsZWdlbmRfc3BlY2llcyksIHNoYXBlID0gMjEsIGFscGhhID0gLjgpICsKICBjb29yZF9maXhlZCgxLjMsIHlsaW0gPSBjKDMyLCA2MCksIHhsaW0gPSBjKC0xMCwgMzApKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArCiAgcGFuZWxfYm9yZGVyKGNvbG9yID0gImdyZXkiLCBzaXplID0gLjUpCgojIGNvbnRpZ3VvdXMgdXMKdXNhID0gbWFwKCJzdGF0ZSIsIHBsb3QgPSBGQUxTRSwgZmlsbCA9IFRSVUUpICU+JSBmb3J0aWZ5KCkgIyAidXNhIgoKbXMzIDwtIG1zICsgCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB3b3JsZCwgYWVzKGdyb3VwID0gZ3JvdXApLCBjb2wgPSAiYmxhY2siLCBmaWxsID0gImdyZXk5MCIsIGx3ZCA9IC4yKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSB1c2EsIGFlcyhncm91cCA9IGdyb3VwKSwgY29sID0gImJsYWNrIiwgZmlsbCA9ICJncmV5OTAiLCBsd2QgPSAuMikgKwogIGdlb21fcG9pbnQoYWVzKHNpemUgPSBOc3R1ZGllcywgZmlsbCA9IGxlZ2VuZF9zcGVjaWVzKSwgc2hhcGUgPSAyMSwgYWxwaGEgPSAuOCkgKwogIGNvb3JkX2ZpeGVkKDEuMywgeWxpbSA9IGMoMjUsIDQ5KSwgeGxpbSA9IGMoLTEyNywgLTY3KSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKwogIHBhbmVsX2JvcmRlcihjb2xvciA9ICJncmV5Iiwgc2l6ZSA9IC41KQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01LjUsIGNhY2hlPVRSVUV9CiMgbWFrZSBib3R0b20gcm93ICgzIG1hcCBpbnNldHMgKyBsZWdlbmQpCmJvdHRvbV9yb3cgPC0gcGxvdF9ncmlkKG1zMywgbXMyLCBOQSwgbXMxLCBOQSwgbGVnZW5kLCBucm93ID0gMSwgbGFiZWxfeCA9IC0uMjcsIGxhYmVsX3kgPSAuOTMsCiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMocmVwKCIiLCA1KSwgIk51bWJlciBvZiAuLi4iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbF93aWR0aHMgPSBjKDIsIDEuMTgsIC4wNiwgLjg1LCAuMDgsIC43KSkKCiMgbWFrZSB3aG9sZSBwbG90IGFzIDEgY29sdW1uLCBiaWcgbWFwIG9uIHRvcCwgYm90dG9tIHJvdyB1bmRlcm5lYXRoCnBsb3RfZ3JpZChtc3gsIGJvdHRvbV9yb3csIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMi40LCAxKSkgKwogIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKC41LCAuNSwgMS41LCAuNSksICJjbSIpKQpgYGAKCmBgYHtyfQpnZ3NhdmUoIi4uL2dyYXBocy9tYXBfaW5zZXRzX2NvbF9zcGVjaWVzLnBkZiIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gNS41LCBzY2FsZSA9IDIpCmBgYAoKCioqKgoKIyBTZXNzaW9uIEluZm8KCmBgYHtyfQpzZXNzaW9uSW5mbygpCmBgYAo=